﻿#pragma once

#include "../../../utils/gui/Control.h"
#include "../../../utils/gui/Label.h"
#include "../../../domain/models/Card.h"

namespace Views {
	/**
	* Różne klasy pomocnicze dla widoków, większość nie została
	* umieszczona w dokumentacji ze względu na swoje małe znaczenie i stosunkową prostotę
	*/
	namespace Helpers {
		/**
		* Klasy pomocnicze graficznego interfejsu użytkownika, np. okna dialogowe.
		*/
		namespace Graphic {
			/**
			* Klasa reprezentująca kontrolkę karty,
			* obsługującą jej podświetlanie i zaznaczanie
			*/
			class CardControl: public Utils::GUI::Control
			{
			protected:
				sf::Color standardColour; /**< Kolor normalny */
				sf::Color hoverColour; /**< Kolor po najechaniu kursorem */
				sf::Color selectedColour; /**< Kolor po zaznaczeniu */

				bool is_selected; /**< Czy karta jest zaznaczona */
				bool is_selectable; /**< Czy kartę można zaznaczyć */

			public:
				/**
				* Abstrakcyjna funkcja, zwracająca kartę powiązaną z tą kontrolką
				*/
				virtual Cards::Card* getCard() = 0;

				/**
				* Funkcja zaznaczająca kontrolkę
				*/
				virtual void select();
				/**
				* Funkcja odznaczająca kontrolkę
				*/
				virtual void unselect();
			protected:
				CardControl();
				virtual void setShape(); /**< Ustawia standardowy kształt formatki */
				 /**
				 * Pozwala zmienić klasom podrzędnym kształt kontrolki (metoda szablonowa)
				 */
				virtual void setCardShape() = 0;
				virtual void setText(); /**< Ustawia tekst kontrolki */

				virtual void MouseEnter(); /**< Zmienia kolor na ten po najechaniu kursorem */
				virtual void MouseLeave(); /**< Zmienia kolor na standardowy */
			};

			/**
			* Generyczna klasa dla każdej z trzech rodzajów kontrolek.
			*/
			template<typename T>
			class GenericCardControl: public CardControl
			{
				T* card;
				Utils::GUI::Label *Text;

			public:
				/**
				* Nadpisuje funkcję z klasy nadrzędnej,
				* pozwalając na zwrócenie karty konkretnego typu (a nie abstrakcyjnego Cards::Card)
				*/
				T* getCard();
				/**
				* @param card Karta związana z kontrolką
				*/
				GenericCardControl(T* card);

				/**
				* Pozwala na zaznaczanie kontrolki
				*/
				virtual void setSelectable();
			protected:
				virtual void setColours(); /**< Ustawia kolory zgodnie z wybranym typem */
				virtual void setCardShape(); /**< Ustawia kształt kontrolki zgodnie z wybranym typem */
				virtual void setText(); /**< Ustawia tekst na kontrolce zgodnie z wybranym typem */
			};

			/**
			* Pomocnicza klasa tworząca kontrolki konkretnego typu, korzystając z mechanizmu RTTI
			*/
			class CardControlFactory
			{
			public:
				/**
				* Jeśli card jest typu Card::Card*, używa mechanizmu RTTI, by dowiedzieć się
				* jakiego typu dziedziczącego z tej klasy jest to obiekt i tworzy dla niego odpowiednią
				* kontrolkę zgodną z typem tego obiektu.
				* Jeśli card jest już któregoś z typów dziedziczących z Card::Card,
				* to od razu tworzy odpowiednią kontrolkę
				* @param card Karta, dla której trzeba utworzyć kontrolkę
				* @return Kontrolka karty
				*/
				template<typename T>
				static CardControl* create(T*);
			};

			typedef GenericCardControl<Cards::PlayerCard> PlayerCardControl;
			typedef GenericCardControl<Cards::WeaponCard> WeaponCardControl;
			typedef GenericCardControl<Cards::RoomCard> RoomCardControl;
		}
	}
}

